import csv
import datetime
import os
from inspect import isclass
    
class CsvPersister(object):
    '''
    	Persists the pojo class instances into the given csv file.
    '''
    def __init__(self, csv_file, use_id=True):
        self.csv_file = csv_file
        if use_id:
            from generate_id import GenerateId
            (path, file_) = os.path.split(csv_file)
            self.id_generator = GenerateId(path)
        else:
            self.id_generator = DummyIdGenerator()

    def _ensure_initialized(func):
        def wrapper(self, target_obj, *args):
            if isclass(target_obj):
                target_object = target_obj()
            else:
                target_object = target_obj
                
            is_empty = True
            if os.path.exists(self.csv_file):
                with open(self.csv_file,'rb') as fr:
                    reader = csv.reader(fr)
                    rows = list(reader)
                    is_empty = (len(rows) == 0)
                
            if is_empty:
                with open(self.csv_file,'wb') as fw:
                    writer = csv.writer(fw)
                    writer.writerow(self._get_headers(target_object))
                    
            return func(self,target_obj,*args)
        return wrapper

    def _check_searchable(func):
        def wrapper(self,*args,**kwarg):
            if isinstance(self.id_generator,DummyIdGenerator):
                return
            return func(self,*args,**kwarg)
        return  wrapper
            
        
        
    def _build_row(self, target_object, id):
        object_fields = target_object.__dict__.items()
        if id is None:
            id =self.id_generator.generate_id(section=target_object.__class__.__name__) 
        row = [id]
                
        for (name,value) in object_fields:
            if isinstance(value,str) or value is None:
                row.append(value)               
            else:
                row.append(str(value))
                
        return row

    def _get_headers(self, target_object):
        headers = ['id']            
        headers.extend([header for (header,value) in target_object.__dict__.items()])
        return headers
    
    @_ensure_initialized    
    def add(self, target_object, id = None):      
        with open(self.csv_file,'a') as f:
            writer = csv.writer(f)
            writer.writerow(self._build_row(target_object,id))

    @_ensure_initialized    
    @_check_searchable
    def remove(self, target_object):                  
        list = self.get_list(target_object.__class__)
        os.remove(self.csv_file)        
        for item in list:
            if int(item.id) != int(target_object.id):  
                id = item.id
                del item.id 
                self.add(item, id)
    
    @_ensure_initialized
    @_check_searchable    
    def get_item(self, target_object):
        list = self.get_list(target_object.__class__)
        for item in list:
            if int(item.id) == int(target_object.id):
                return item
        return None
                    
                    
    @_ensure_initialized    
    def get_list(self, target_object_clazz):
        target_list = []
        with open(self.csv_file,'rb') as fr:
            reader = csv.reader(fr)
            for row in list(reader)[1:]:
                i = 1
                target_object = target_object_clazz()
                for (name,value) in target_object.__dict__.items():
                    setattr(target_object,name, row[i])
                    i += 1
                    
                target_object.id = row[0]
                target_list.append(target_object)

        return target_list
    

class DummyIdGenerator():
    def generate_id(self,section=''):
        return 0
    
 ############# TESTING IN MAIN ###############
            
class TestObject(object):
    def __init__(self,name,start_date,duration,current_status,next_status):
        self.name = name
        self.start_date = start_date
        self.duration = duration
        self.current_status = current_status
        self.next_status = next_status
        

if __name__ == '__main__':
    ctp = CsvPersister('/tmp/test_object.csv')
    tobj = TestObject('serdar', datetime.date.today(), 20, 10,100)
    ctp.add(tobj)
    
